//#define VERBOSE
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <sstream>
#include <cmath>

using namespace std;

typedef struct TPoint {
	int x, y;
} TPoint;

TPoint incDir[8];
int intDirs[][2] = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};
string chDirs[] = {"N", "NE", "E", "SE", "S", "SW", "W", "NW"};
bool hasDir[110][110][8];

TPoint curPos;
int curDir;

const int TURN = 0;
const int GO = 1;
const int STOP = 2;
const int END = 3;
const int UNKNOWN = 4;
typedef struct TCommand {
	int type, value;
} TCommand;

ostream& operator << (ostream& out, const TCommand& cmd) {
	return out << "command: " << cmd.type << " " << cmd.value;
}

bool isNum(const string& x) {
	stringstream ss(stringstream::in | stringstream::out);
	ss << x;
	int d;
	ss >> d;
	bool readIntState = ss.fail();
	string left;
	ss >> left;
	if (left.length() > 0) return false;
	return !readIntState;
}

bool outMap(TPoint x) {
	return (x.x < -50 || x.x > 50 || x.y < -50 || x.y > 50);
}

TCommand unknownCmd;

TCommand parse(char *line) {
	TCommand cmd;
// 	string sline = string(line);
// 	if (sline.find("STOP") != string::npos) {
// 		cmd.type = STOP;
// 		return cmd;
// 	}
	stringstream ss(stringstream::in | stringstream::out);
	ss << line;
	string bufStr;
	ss >> bufStr;
	
	if (bufStr == "TURN")
		cmd.type = TURN;
	else if (bufStr == "GO")
		cmd.type = GO;
	else if (bufStr == "STOP")
		cmd.type = STOP;
	else if (bufStr == "END")
		cmd.type = END;
	else
		return unknownCmd;

	bufStr.clear();
	ss >> bufStr;
	if (cmd.type == GO) {
		if (bufStr == "STRAIGHT") {
			bufStr.clear();
			ss >> bufStr;
		}
		
		if (isNum(bufStr)) {
			string bufStr2 = bufStr;
			bufStr.clear();
			ss >> bufStr;
			if (bufStr.length() > 0)
				return unknownCmd;
			ss.clear();
			ss << bufStr2;
			ss >> cmd.value;
			if (cmd.value < 1 || cmd.value > 99)
				return unknownCmd;
			return cmd;
		}
		else
			return unknownCmd;
	}
	else if (cmd.type == TURN) {
		cmd.value = 0;
		if (bufStr == "HALF") {
			cmd.value = -1;
			bufStr.clear();
			ss >> bufStr;
		}
		else if (bufStr == "SHARP") {
			cmd.value = 1;
			bufStr.clear();
			ss >> bufStr;
		}

		if (bufStr == "LEFT") {
			bufStr.clear();
			ss >> bufStr;
			if (bufStr.length() > 0)
				return unknownCmd;
			cmd.value = -(2 + cmd.value);
		}
		else if (bufStr == "RIGHT") {
			bufStr.clear();
			ss >> bufStr;
			if (bufStr.length() > 0)
				return unknownCmd;
			cmd.value = 2 + cmd.value;
		}
	}
	else if (cmd.type == END || cmd.type == STOP) {
		if (bufStr.length() > 0) return unknownCmd;
	}

	return cmd;

}

TPoint operator * (int s, const TPoint& x) {
	TPoint res;
	res.x = s*x.x;
	res.y = s*x.y;
	return res;
}

TPoint operator + (const TPoint& x, const TPoint& y) {
	TPoint res;
	res.x = x.x + y.x;
	res.y = x.y + y.y;
	return res;
}

bool onThroughway(TPoint curPos) {
	if (curPos.x == -50 || curPos.y == -50 || curPos.x == 50 || curPos.y == 50)
		return true;
	if (curPos.x == 0 || curPos.y == 0 || abs(curPos.x) == abs(curPos.y))
		return true;
	return false;

}

bool onThroughway(void) {
	return onThroughway(curPos);
}

int throughwayDir(TPoint pos) {
	int state = 0;
	if (pos.x%50 == 0)
		state += 1;
	if (pos.y%50 == 0)
		state += 2;
	if (pos.x == pos.y)
		state += 4;
	if (pos.x == -pos.y)
		state += 8;
	return state;
}

TPoint goBack(TPoint curPos, int curDir) {
	return curPos + incDir[(curDir+4)%8];
}

int enteringOrLeavingThroughway(int changingDir) {
	TPoint lastPos = goBack(curPos, curDir);
	int newDir = (curDir+changingDir+8)%8;
	TPoint newPos = curPos + incDir[newDir];
	bool willOnThroughway = false;
	bool isOnThroughway = false;
	if (onThroughway(curPos) && onThroughway(newPos))
		if ((throughwayDir(curPos) & throughwayDir(newPos)) > 0) {
			willOnThroughway = true;
		}
	if (onThroughway(lastPos) && onThroughway(curPos))
		if ((throughwayDir(lastPos) & throughwayDir(curPos)) > 0) {
			isOnThroughway = true;
		}
	if (!isOnThroughway && willOnThroughway) return 1;
	if (isOnThroughway && !willOnThroughway) return 2;
	return 0;
}

bool onCircle() {
	return abs(curPos.x%50)+abs(curPos.y%50) == 0;
}

void execute(TCommand cmd) {
	switch (cmd.type) {
	case GO:
		TPoint newPos;
		if (!hasDir[curPos.x+50][curPos.y+50][curDir]) {
// 			while(true);
			return;
		}
		newPos = curPos + cmd.value*incDir[curDir];
		if (outMap(newPos)) return;
		curPos = newPos;
		break;
	case TURN:
		int newDir = (curDir+cmd.value+8)%8;
		int checkRes = enteringOrLeavingThroughway(cmd.value);
		if (checkRes>0 && !onCircle()) {
			if (checkRes == 1) {//entering
				TPoint newPos = curPos + incDir[newDir];
				if ((throughwayDir(curPos) & throughwayDir(newPos)) > 3) {
					if (cmd.value != -3) {
#ifdef VERBOSE
						cout << "illegal turn, ignore!!!!!!!!!!!!!" << endl;
#endif
						return;
					}
				}
				else {
					if (cmd.value != -2) {
#ifdef VERBOSE
						cout << "illegal turn, ignore!!!!!!!!!!!!!" << endl;
#endif
						return;
					}
				}
			}
			else {//leaving
				TPoint lastPos = goBack(curPos, curDir);
				if ((throughwayDir(lastPos) & throughwayDir(curPos)) > 3) {
					if (cmd.value != -3) {
#ifdef VERBOSE
						cout << "illegal turn, ignore!!!!!!!!!!!!!" << endl;
#endif
						return;
					}
				}
				else {
					if (cmd.value != -2) {
#ifdef VERBOSE
						cout << "illegal turn, ignore!!!!!!!!!!!!!" << endl;
#endif
						return;
					}
				}
			}
		}

		if (!hasDir[curPos.x+50][curPos.y+50][newDir]) {
#ifdef VERBOSE
			cout << "impossible turn, ignore!!!!!!!!!!!!!" << endl;
#endif
			return;
		}
		curDir = newDir;
		execute(parse("GO 1"));
		break;
	}
}

void show(void) {
	cout << "A" << abs(curPos.x) << ((curPos.x>=0)?'E':'W') << " "
		<< "S" << abs(curPos.y) << ((curPos.y>=0)?'N':'S') << " "
		<<  chDirs[curDir] << endl;
}

void goBack(void) {
	curPos = goBack(curPos, curDir);
}

int main(void)
{
	unknownCmd.type = UNKNOWN;
	for (int i=0; i<8; ++i) {
		incDir[i].x = intDirs[i][0];
		incDir[i].y = intDirs[i][1];
	}
	memset(hasDir, 0, 110*110*8);
	for (int i=0; i<=100; ++i)
		for (int j=0; j<=100; ++j)
			for (int k=0; k<8; k+=2)
				hasDir[i][j][k] = true;
	for (int i=0; i<=100; ++i) {
		hasDir[i][0][4] = false;
		hasDir[i][100][0] = false;
		hasDir[0][i][6] = false;
		hasDir[i][100][2] = false;
	}
	for (int i=0; i<=50; ++i) {
		hasDir[i][50+i][1] = true;
		hasDir[i][50+i][5] = true;
		hasDir[i+50][100-i][7] = true;
		hasDir[i+50][100-i][3] = true;
		hasDir[100-i][50-i][1] = true;
		hasDir[100-i][50-i][5] = true;
		hasDir[50-i][i][7] = true;
		hasDir[50-i][i][3] = true;
	}
	for (int i=0; i<=100; ++i) {
		hasDir[i][i][1] = true;
		hasDir[i][i][5] = true;
		hasDir[i][100-i][7] = true;
		hasDir[i][100-i][3] = true;
	}

	for (int i=1; i<8; i+=2) {
		hasDir[0][0][i] = false;
		hasDir[0][100][i]= false;
		hasDir[100][0][i] = false;
		hasDir[100][100][i] = false;
	}
	hasDir[0][0][1] = true;
	hasDir[0][100][3] = true;
	hasDir[100][100][5] = true;
	hasDir[100][0][7] = true;

	hasDir[0][50][7] = hasDir[0][50][5] = false;
	hasDir[50][0][3] = hasDir[50][0][5] = false;
	hasDir[100][50][1] = hasDir[100][50][3] = false;
	hasDir[50][100][1] = hasDir[50][100][7] = false;

	string bufStr;
	bool end = false;
	char line[100];
	while(true) {
		memset(line, 0, 100);
		cin.getline(line, 100);
		if (strlen(line) == 0) continue;
		stringstream ss(stringstream::in | stringstream::out);
		ss << line;

		for (int i=0; i<2; ++i) {
			ss >> bufStr;
			if (bufStr == "END") {
				end = true;
				break;
			}
			int* p;
			if (bufStr.length() == 0) {
				while (true);
			}
			else if (bufStr[0] == 'A') p = &curPos.x;
			else if (bufStr[0] == 'S') p = &curPos.y;
			else {
				cout << "error" << endl;
				cout << bufStr << endl;
				exit(0);
				while (true);
			}
			stringstream ss2(stringstream::in | stringstream::out);
			ss2 << bufStr;
			char ch;
			ss2 >> ch;
			ss2 >> (*p);
			ss2 >> ch;
			if (ch == 'W' || ch == 'S') *p = -*p;
		}
		ss >> bufStr;
		for (int i=0; i<8; ++i)
			if (chDirs[i] == bufStr) {
				curDir = i;
				break;
			}
#ifdef VERBOSE
		show();
#endif
		execute(parse("GO 1"));
#ifdef VERBOSE
 		show();
#endif
		while(!end) {
			cin.getline(line, 100);
#ifdef VERBOSE
 			cout << "line: " << line << endl;
#endif
			TCommand cmd = parse(line);
#ifdef VERBOSE
			cout << cmd << endl;
#endif
			execute(cmd);
#ifdef VERBOSE
			show();
#endif
			end = (cmd.type == END);
			if (cmd.type == STOP) {
				if (onThroughway()) {
					TPoint bakPos = curPos;
					goBack();
					if (onThroughway()) {
						if ((throughwayDir(bakPos) & throughwayDir(curPos))>0)
							cout << "Illegal stopping place" << endl;
						else
							show();
					}
					else
						show();
				}
				else {
					goBack();
					show();
				}
				break;
			}
		}

		if (end) break;
#ifdef VERBOSE
		cout << endl;
#endif
	}

	return 0;
}